#include <stdio.h>
#include <string.h>

typedef struct
    {
        char name[20];
        int age;
        float sorce;
    }student;

//以char类型指针，每次交换一个字节的数据，确保能交换任意类型数据
void Swap(char* elem1, char* elem2, size_t width){
    size_t i = 0;
    for(i = 0; i < width; i++){
        char tmp = *(elem1 + i);
        *(elem1 + i) = *(elem2 + i);
        *(elem2 + i) = tmp;
    }
}

//整型比较大小
int int_cmp(const void* elem1, const void* elem2){
    return *((int*)elem1) - *((int*)elem2);
}

//字符串比较大小
int char_cmp(const void* elem1, const void* elem2){
    return strcmp((char*)elem1, (char*)elem2);
}

//结构体比较大小
//整型
int Strint_cmp(const void* elem1, const void* elem2){
    return ((student*)elem1)->age - ((student*)elem2)->age;
}
//字符串
int Strchar_cmp(const void* elem1, const void* elem2){
    return strcmp(((student*)elem1)->name,((student*)elem2)->name);
}
//浮点数
int Strfloat_cmp(const void* elem1, const void* elem2){
    return ((student*)elem1)->sorce - ((student*)elem2)->sorce;
}

//利用冒泡排序模拟qsort库函数
void bubblesort(void* base, size_t sz, size_t width, int (*cmp)(void* ,void* )){
    size_t i = 0;
    for(i = 0; i < sz; i++){
        for(size_t j = 0; j < sz - 1 - i;j++){
            if(cmp((char*)base + j * width,(char *)base + (j + 1) * width) > 0)
                Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
        }
    }

}

int main(){
    //整型
    int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
    size_t width = sizeof(int);
    size_t sz = sizeof(arr) / width;
    bubblesort(arr, sz, width, (void*)int_cmp);

    //字符型
    for (size_t i = 0; i< sz; i++){
        printf( "%d ", arr[i]);
    }
    printf("\n");
    char arr1[] = "wyx-cherry-blossomwyx";
    bubblesort(arr1, strlen(arr1), sizeof(char), (void*) char_cmp);
    printf("%s\n", arr1);

    //结构体
    student stu[3] = {{"Zhangshan", 25, 59.5f}, {"Lisi", 29, 75}, {"Wangwu", 26, 100}};
    //bubblesort(stu, sizeof(stu) / sizeof(stu[0]), sizeof(student), (void*)Strint_cmp);
    //bubblesort(stu, sizeof(stu) / sizeof(stu[0]), sizeof(student), (void*)Strchar_cmp);
    bubblesort(stu, sizeof(stu) / sizeof(stu[0]), sizeof(student), (void*)Strfloat_cmp);
    for(size_t i = 0; i < sizeof(stu) / sizeof(stu[0]); i++){
        printf("%s %d %.1f",stu[i].name, stu[i].age, stu[i].sorce);
        printf("\n");
    }
    return 0;
}